package com.polaris.live.ui.live.widget.adapter

import android.text.BidiFormatter
import android.text.TextDirectionHeuristics
import android.view.View
import androidx.lifecycle.LifecycleCoroutineScope
import com.blankj.utilcode.util.ColorUtils
import com.blankj.utilcode.util.SpanUtils
import com.blankj.utilcode.util.SpanUtils.ALIGN_CENTER
import com.blankj.utilcode.util.StringUtils
import com.polaris.live.R
import com.polaris.live.adapter.live.LiveMessageAdapter
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.util.loadIfPresent
import com.polaris.live.databinding.LiveMessageGiftItemBinding
import com.polaris.live.im.sfs.bean.live.SendLiveMessage
import com.polaris.live.im.sfs.bean.live.ext.MessageUserExtBean
import com.polaris.live.im.sfs.bean.live.payload.InviteGiftPayloadBean
import com.polaris.live.im.sfs.bean.live.payload.LuckGiftRewardDto
import com.polaris.live.manager.LiveStateManager
import com.polaris.live.translation.R.string
import com.polaris.live.ui.message.widget.single_message.AbstractLiveMessageItemHolder
import com.polaris.live.utils.CommonUtils
import com.polaris.live.utils.image.ImageUtils
import com.polaris.live.utils.image.ImageUtils.loadNetImageDrawable
import com.polaris.live.utils.viewscope.autoDisposeScope
import com.polaris.live.widget.avatar.FrameImageUtils
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.util.Locale

/**
 * LiveMessageGiftItem
 *
 * @author Created by 半仙 on 2023/9/25/025 17:47
 */
class LiveMessageGiftItem(
    adapter: LiveMessageAdapter,
    binding: LiveMessageGiftItemBinding,
    private val lifecycleScope: LifecycleCoroutineScope?
) : AbstractLiveMessageItemHolder<LiveMessageGiftItemBinding>(adapter, binding) {

    override fun bind(item: SendLiveMessage) {
        val payload = item.payload as? InviteGiftPayloadBean?
            ?: return

        mBinding.apply {
            val ext = item.ext as? MessageUserExtBean?
            if (payload.reward == null || payload.reward.times == 0) {
                avatarImg.setImageUrl(ext?.user?.avatar, ext?.user?.userId)
                avFv.setFrameImage(FrameImageUtils.urlToFrameImageBean(ext?.user?.avatarFrame))
                vipView.setVipLevel(ext?.user?.vipLevel)
                handleTextSpan(payload, item)
                handleHeadSpan(item)

                llBack.visibility = View.VISIBLE
                llLuck.visibility = View.GONE
            } else {
                avatarImgLuck.setImageUrl(ext?.user?.avatar, ext?.user?.userId)
                avFv2.setFrameImage(FrameImageUtils.urlToFrameImageBean(ext?.user?.avatarFrame))
                vipView1.setVipLevel(ext?.user?.vipLevel)
                handleLuckSpan(payload, payload.reward, item)
                handleHeadSpan2(item)

                llBack.visibility = View.GONE
                llLuck.visibility = View.VISIBLE
            }
        }
    }

    private fun LiveMessageGiftItemBinding.handleTextSpan(
        payload: InviteGiftPayloadBean,
        item: SendLiveMessage,
    ) {
        loadIfPresent({ item.span1 }, {
            mBinding.root.autoDisposeScope.launch {
                try {
                    val giftImage = loadNetImageDrawable(
                        mBinding.root.context,
                        ImageUtils.imgPath(payload.gift.pic),
                        24, 24
                    )
                    val spanBuild = SpanUtils.with(tvText)

                    withContext(CoroutineScopeManager.mainDispatcher) {
                        val lineHeight = mBinding.tvText.lineHeight
                        val isShowName = if (LiveStateManager.isCalling()) {
                            ""
                        } else {
                            " ${payload.nickname} "
                        }
                        spanBuild.append(" ${StringUtils.getString(string.send_out)}$isShowName")
                            .setLineHeight(2 * lineHeight, ALIGN_CENTER)
                            .setForegroundColor(ColorUtils.getColor(R.color.white))
                        if (mBinding.root.context.resources.configuration.layoutDirection == View.LAYOUT_DIRECTION_RTL) {
                            val na = BidiFormatter.getInstance(Locale.getDefault()).unicodeWrap(
                                payload.gift.giftName,
                                TextDirectionHeuristics.ANYRTL_LTR
                            )
                            spanBuild.append(" $na ")
                                .setLineHeight(2 * lineHeight, ALIGN_CENTER)
                                .setForegroundColor(ColorUtils.getColor(R.color.color_fff1b1))

                            if (giftImage != null) {
                                spanBuild.appendImage(giftImage, ALIGN_CENTER)
                            }
                            spanBuild.append("×${payload.giftCount}")
                                .setLineHeight(2 * lineHeight, ALIGN_CENTER)
                                .setForegroundColor(ColorUtils.getColor(R.color.white))
                        } else {
                            spanBuild.append("${payload.gift.giftName} ")
                                .setLineHeight(2 * lineHeight, ALIGN_CENTER)
                                .setForegroundColor(ColorUtils.getColor(R.color.color_fff1b1))
                            if (giftImage != null) {
                                spanBuild.appendImage(giftImage, ALIGN_CENTER)
                            }
                            spanBuild.append("×${payload.giftCount}")
                                .setLineHeight(2 * lineHeight, ALIGN_CENTER)
                                .setForegroundColor(ColorUtils.getColor(R.color.white))
                        }

                        emit(spanBuild.create())
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }, {
            tvText.text = it
            item.span1 = it
        })
    }

    private fun LiveMessageGiftItemBinding.handleHeadSpan(item: SendLiveMessage) {
        val ext = item.ext as? MessageUserExtBean?

        CommonUtils.setNumberMedal(lifecycleScope, ext?.user?.numberMedal, mBinding.pagImageMe, mBinding.ivImageMe)

        loadIfPresent({ item.span2 }, {
            mBinding.root.autoDisposeScope.launch {
                try {
                    val spanBuild = CommonUtils.setSpanData(tvName, item, mAdapter.context)

                    withContext(CoroutineScopeManager.mainDispatcher) {
                        emit(spanBuild.create())
                    }
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }, {
            tvName.text = it
            item.span2 = it
        })
    }

    private fun LiveMessageGiftItemBinding.handleLuckSpan(
        payload: InviteGiftPayloadBean,
        reward: LuckGiftRewardDto,
        item: SendLiveMessage,
    ) {
        loadIfPresent({ item.span1 }, {
            val span = SpanUtils.with(luckText)
                .append(StringUtils.getString(string.send_out))
                .setForegroundColor(ColorUtils.getColor(R.color.white))
                .append(" ${payload.gift.giftName} ")
                .setForegroundColor(ColorUtils.getColor(R.color.color_fff1b1))
                .append("×${payload.giftCount} ${StringUtils.getString(string.get_it)} ")
                .setForegroundColor(ColorUtils.getColor(R.color.white))
                .append(StringUtils.getString(string.get_multiple, reward.times))
                .setForegroundColor(ColorUtils.getColor(R.color.color_fff1b1))
                .append(" ${StringUtils.getString(string.win_num, reward.coin)} ")
                .setForegroundColor(ColorUtils.getColor(R.color.white))
                .appendImage(R.drawable.small_diamond)
                .create()

            emit(span)
        }, {
            luckText.text = it
            item.span1 = it
        })
    }

    private fun LiveMessageGiftItemBinding.handleHeadSpan2(item: SendLiveMessage) {
        val ext = item.ext as? MessageUserExtBean?

        CommonUtils.setNumberMedal(lifecycleScope, ext?.user?.numberMedal, mBinding.pagImageMe2, mBinding.ivImageMe2)

        loadIfPresent({ item.span2 }, {
            mBinding.root.autoDisposeScope.launch {
                try {
                    val spanBuild = CommonUtils.setSpanData(liveHead, item, mAdapter.context)
                    withContext(CoroutineScopeManager.mainDispatcher) {
                        emit(spanBuild.create())
                    }
                } catch (_: Exception) {
                }
            }
        }, {
            liveHead.text = it
            item.span2 = it
        })
    }
}